package affd.logic;

import java.io.File;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class ConverterClient {
	
	private static Logger logger = Logger.getLogger("Logic");
	
	public static final String EXTENSION_HTML = "html";
	public static final String EXTENSION_PDF = "pdf";
	public static final String FUNCTION_CONVERT = "Converter.convert";
	public static final String DEFAULT_PORT = "8110";
	public static final String DEFAULT_HOST = "localhost";
	public static final String DEFAULT_RPC = "/RPC2";
	public static final String DEFAULT_PROTOCOL = "http://";
	
	private XmlRpcClient client;
	
	private String host;
	private String port;
	
	/**
	 * Constructs a converter client.
	 */
	public ConverterClient(String host, String port) {
		// Set host
		if(host != null) {
			this.host = host;
		} else {
			this.host = DEFAULT_HOST;
			logger.log(Level.WARNING, "No host defined. Using default host " + DEFAULT_HOST + " !");
		}

		// Set port
		if(port != null) {
			this.port = port;
		} else {
			this.port = DEFAULT_PORT;
			logger.log(Level.WARNING, "No port defined. Using default port " + DEFAULT_PORT + " !");
		}
		
		// Create client
		client = new XmlRpcClient();
	}
	
	/**
	 * Connects to the specified OpenOffice converter.
	 * 
	 * @throws LogicException
	 */
	protected void connect() throws LogicException {
		// Construct url
		String url = DEFAULT_PROTOCOL + host + ":" + port + DEFAULT_RPC;
		
		try {
			// Create configuration
			XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
			config.setServerURL(new URL(url));

			// Use compression
			config.setGzipCompressing(true);
			config.setGzipRequesting(true);

			// Create client
			client.setConfig(config);
		} catch (Exception e) {
			throw new LogicException("Failed to connect " + url + " !", e);
		}
	}
	
	/**
	 * 
	 * 
	 * @param filename The filename of the input file
	 * @param outputExtension The extension of the output file
	 * @return The name of the output file
	 * @throws LogicException
	 */
	public String convert(String filename, String outputExtension) throws LogicException{
		if(getExtension(filename).equalsIgnoreCase(outputExtension)) {
			return filename;
		}
		
		// Create absolute paths
		String inputFilename = new File(filename).getAbsolutePath();
		String outputFilename = new File(setExtension(filename, outputExtension)).getAbsolutePath();
		
		// Connect and create output filename
		connect();
		
		// Convert
		Object[] paramValues = new Object[] {inputFilename, outputFilename};
		Object returnValue = null;
		try {
			returnValue = client.execute(FUNCTION_CONVERT, paramValues);
		}
		catch(Exception e) {
			throw new LogicException("Failed to convert " + filename + " !", e);
		}
		
		// TODO Check return value
		
		return outputFilename;
	}
	
	/**
	 * Gets the specified file's extension.
	 * 
	 * @param filename Filename to be processed.
	 * @return Extracted file extension.
	 */
	public static String getExtension(String filename) {
		return filename.substring(filename.lastIndexOf(".") + 1);
	}

	/**
	 * Sets the file's extension to specified extension.
	 * 
	 * @param filename Filename to be processed.
	 * @param extension Extension to be set.
	 * @return Filename with the specified extension.
	 */
	public static String setExtension(String filename, String extension) {
		// Remove old extension
		int index = filename.lastIndexOf('.');
		if(index >= 0) {
			filename = filename.substring(0, index);
		}
		
		return filename + "." + extension;
	}

}
